'''
Created on May 13, 2010

@author: roni
'''
from projectConstants import ProjectConstants
from ns2Scenario import Ns2Scenario
import groupUtils
from experimentRunner import ExperimentRunner
import logging

class ExperimentSetRunner(object):
    ''' Runs a set of experiments, by choosing a different set of abnormal nodes on the same scenario '''
    OUTPUT_TRACE_FILE = "trace.txt"
    
    def __init__(self,scenario):
        self.scenario = scenario
        self.runner = ExperimentRunner()
        self.verify_diagnosis = True
        self.write_abnormals = False
    
    def run_all_abnormals(self,results_file_name,config_parameters,max_abnormals=-1):
        ''' Run diagnosis on all possible combinations of abnormal nodes '''
        possible_abnormals = set()
        for agent in self.scenario.agents:
            possible_abnormals.update(self.scenario.agent_to_path[agent])
            
        # Current GDE focuses on abnormals in the paths
        for agent in self.scenario.agents:
            possible_abnormals.difference_update(self.scenario.agent_to_flow[agent])
        
        if max_abnormals<0:
            max_abnormals = len(possible_abnormals)
        
        # Try any size of abnormals set size
        results_file = file(results_file_name ,'a')
        for i in xrange(1,max_abnormals+1):
            all_subsets = groupUtils.all_subsets_of_size(i,possible_abnormals)
            for abnormals in all_subsets:
                # Set the abnormal nodes
                node_to_delay = dict()
                for abnormal in abnormals:
                    node_to_delay[abnormal] = Ns2Scenario.LINK_DELAY*1000

                # Run the diagnosis                
                logging.info("Diagnose scenario with %d abnormals [%s]" % (i,abnormals))                
                (found, num_of_diagnosises, runtime) = self.runner.run(self.scenario, \
                                                    ExperimentSetRunner.OUTPUT_TRACE_FILE,\
                                                    node_to_delay)
                
#                if found==False:
#                    logging.error("Correct diagnosis has not been found")
#                    (found, num_of_diagnosises, runtime) = self.runner.run(self.scenario_file_name, \
#                                                        ExperimentSetRunner.OUTPUT_TRACE_FILE,\
#                                                        node_to_delay)
                    
                
                # Original flow to details
                if self.verify_diagnosis:
                    logging.info("Verifying diagnosis...")
                    original_flow_to_details = self.runner.run_abnormal_simulation(self.scenario, node_to_delay)                
                    self.runner.verify_diagnosis(self.scenario, original_flow_to_details)
                    logging.info("Verified all diagnosis for [%s]" % abnormals)
                # Write results
                for parameter in config_parameters:
                    results_file.write("%s    " % parameter)    
                results_file.write("%d    %s    %d    %f4.3" % (i,found,num_of_diagnosises,runtime))
                if self.write_abnormals:
                    for abnormal in abnormals: 
                        results_file.write("%s    " % abnormal)
                results_file.write("\n")
                results_file.flush()
        results_file.close()
    
        
        
        
        